/* Copyright (c) 2004-2008, Andriy Nikolov
 * All rights reserved.
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
package org.processmining.email;

import java.util.*;

/**
 * <p>Represents one message recipient/sender
 *
 * @author Andriy Nikolov
 * @version 1.0
 */
public class EMailRecipient {

  String name;
  Vector aliases;
  Vector messageList;
  boolean active;

  public EMailRecipient() {
    aliases = new Vector();
    messageList = new Vector();
    active = true;
  }

  /**
   * Creates a EMailRecipient with a specific name.
   *
   * @param name String
   */
  public EMailRecipient(String name) {
    this.name = name;
    aliases = new Vector();
    messageList = new Vector();
    aliases.add(name);
    active = true;
    if(name.equals("")) {
      active = false;
    }
  }

  /**
   * Sets the recipient's name.
   *
   * @param name String
   */
  public void setName(String name) {
    this.name = name;
    if(!aliases.contains(name)) {
      aliases.add(name);
    }
  }

  /**
   * Gets the recipient's name.
   *
   * @return String
   */
  public String getName() {
    return name;
  }

  /**
   * Adds an additional name for the recipient (e.g. new e-mail address or a
   * name in a different format).
   *
   * @param alias String
   */
  public void addAlias(String alias) {
    if (!aliases.contains(alias)) {
      if (aliases.size()==0) {
        name = alias;
      }
      aliases.add(alias);
    }
  }

  /**
   * Removes one of the additional names for the recipient by its index in the
   * list
   *
   * @param index int
   */
  public void removeAlias(int index) {
    String alias;
    alias = (String)aliases.get(index);
    if(aliases.size()>1) {
      aliases.remove(index);
      if(alias.equals(name)) {
        name = (String)aliases.get(0);
      }
    }
  }

  /**
   * Gets a complete list of the recipient's names
   *
   * @return Vector
   */
  public Vector getAliases() {
    return aliases;
  }

  /**
   * Gets an alias with a specific index
   *
   * @param i int
   * @return String
   */
  public String getAlias(int i) {
    return (String)aliases.get(i);
  }

  /**
   * Specifies if the recipient will be included/excluded from the analysis
   *
   * @param value boolean
   */
  public void setActive(boolean value) {
    active = value;
    EMailMessage mes;
    for(int i=0;i<messageList.size();i++) {
      mes = (EMailMessage)messageList.get(i);
      mes.setActive(mes.hasActiveRecipients());
    }
  }

  /**
   * Checks if the recipient is included into analysis.
   *
   * @return boolean
   */
  public boolean isActive() {
    return active;
  }

  /**
   * Checks if two EMailRecipient objects probably describe the same person
   *
   * @param rec EMailRecipient
   * @return boolean
   */
  public boolean isProbablyEqual(EMailRecipient rec) {
    boolean value = false;
    int i, j;
    String alias1, alias2;
    for(i=0;i<aliases.size();i++) {
      alias1 = (String)aliases.get(i);
      for (j=0;j<rec.getAliases().size();j++) {
        alias2 = (String)rec.getAlias(j);
        if (equalNames(alias1, alias2))
          return true;
      }
    }
    return value;
  }

  private String getNamePart(String alias) {
    String firstPart;
    try {
      if (alias.indexOf('@')!=-1) {
        firstPart = alias.substring(0, alias.indexOf('@'));
      } else {
        firstPart = alias;
      }
      return firstPart;
    } catch (Exception e) {
      e.printStackTrace();
      return null;
    }
  }

  private String getDomainPart(String alias) {
    String domainPart;
    try {
      domainPart = alias.substring(alias.indexOf('@'));
      return domainPart;
    } catch (Exception e) {
      e.printStackTrace();
      return null;
    }
  }

  private boolean equalNames(String alias1, String alias2) {
    if(getNamePart(alias1).equalsIgnoreCase(getNamePart(alias2)))
      return true;
    else
      return false;
  }

  /**
   * Adds a message to the list of messages related to this recipient(sender)
   *
   * @param mes EMailMessage
   */
  public void addMessage(EMailMessage mes) {
    messageList.add(mes);
  }

  /**
   * Returns the list of messages related to the current recipient
   *
   * @return Vector
   */
  public Vector getMessageList() {
    return messageList;
  }

  /**
   * Merges the current recipient with another one.
   *
   * @param with EMailRecipient
   */
  public void merge(EMailRecipient with) {
    Vector mlist;
    int i, j;
    EMailMessage mes;
    if(this.equals(with))
      return;

    for (i=0;i<with.getAliases().size();i++) {
      if (!aliases.contains(with.getAlias(i))) {
        aliases.add(with.getAlias(i));
      }
    }
    for (i=0;i<with.getMessageList().size();i++) {
      if (!messageList.contains(with.getMessageList().get(i))) {
        messageList.add(with.getMessageList().get(i));
      }
    }
    mlist = with.getMessageList();
    for (i=0;i<mlist.size();i++) {
      mes = (EMailMessage)mlist.get(i);
      if (mes.getFrom().equals(with)) {
        mes.setFrom(this);
      }
      while (mes.getTo().indexOf(with)!=-1) {
        mes.getTo().set(mes.getTo().indexOf(with), this);
      }
      while (mes.getCc().indexOf(with)!=-1) {
        mes.getCc().set(mes.getCc().indexOf(with), this);
      }
      while (mes.getBcc().indexOf(with)!=-1) {
        mes.getBcc().set(mes.getBcc().indexOf(with), this);
      }
    }
  }

}
